#!/usr/bin/ruby -w

require 'test/unit'
require 'shardeddb'

class ShardedDbExceptionsTest < Test::Unit::TestCase
  HOST_PATTERN = "dbhost%d"
  DB_PATTERN = "db%d"
  SHARD_COUNT = 60
  WRONG_USERNAME = 'wronguser'
  WRONG_PASSWORD = 'wrongpassword'
  RIGHT_USERNAME = 'rightuser'
  RIGHT_PASSWORD = 'rightpassword'
  WRONG_QUERY = "Select * from ;Customers;"
  
  def test_single_shard_wrong_credentials()
    db = ShardedDb.new ShardedDb::QueryType::SINGLE_SHARD, WRONG_USERNAME,
                        WRONG_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.connect 2
        assert false, "connect() did not throw exception when credentials" +
               " are wrong."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error connecting to database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_all_shards_wrong_credentials()
    db = ShardedDb.new ShardedDb::QueryType::ALL_SHARDS, WRONG_USERNAME,
                      WRONG_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.connect
        assert false, "connect() did not throw exception when credentials" +
               " are wrong."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error connecting to database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_single_shard_query_without_connection()
    db = ShardedDb.new ShardedDb::QueryType::SINGLE_SHARD, WRONG_USERNAME,
                       WRONG_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.query WRONG_QUERY
        assert false, "query() did not throw exception when not connected " +
               "to database."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error while querying: connection not established"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_all_shards_query_without_connection()
    db = ShardedDb.new ShardedDb::QueryType::ALL_SHARDS, WRONG_USERNAME,
                       WRONG_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.query WRONG_QUERY
        assert false, "query() did not throw exception when not connected " +
               "to database."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error while querying: connection not established"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_single_shard_faulty_query()
    db = ShardedDb.new ShardedDb::QueryType::SINGLE_SHARD, RIGHT_USERNAME,
                       RIGHT_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.connect 2
        db.query WRONG_QUERY
        assert false, "query() did not throw exception when invoked with " +
               "an invalid query."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error querying database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_all_shards_faulty_query()
    db = ShardedDb.new ShardedDb::QueryType::ALL_SHARDS, RIGHT_USERNAME,
                       RIGHT_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.connect
        db.query WRONG_QUERY
        assert false, "query() did not throw exception when invoked with " +
               "an invalid query."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error querying database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_unknown_shard_wrong_credentials()
    db = ShardedDb.new ShardedDb::QueryType::UNKNOWN_SHARD, WRONG_USERNAME,
                       WRONG_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.query WRONG_QUERY
        assert false, "connect() did not throw exception when credentials" +
               " are wrong."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error connecting to database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end

  def test_unknown_shard_faulty_query()
    db = ShardedDb.new ShardedDb::QueryType::UNKNOWN_SHARD, RIGHT_USERNAME,
                       RIGHT_PASSWORD, HOST_PATTERN, DB_PATTERN, SHARD_COUNT
    3.times do
      begin
        db.query WRONG_QUERY
        assert false, "query() did not throw exception when invoked with " +
               "an invalid query."
      rescue Exception => e
        assert_instance_of ShardedDb::Error, e
        expected_msg = "Error querying database"
        assert_equal e.message[0, expected_msg.length], expected_msg
      end
    end
  end
end
